package com.fany.utils;

import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.*;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ThumbnailUtils;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.ListView;
import com.fany.fastsearcher.R;
import com.fany.utils.FileHelper.FileKind;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.HashMap;

import static com.fany.utils.FileHelper.FileKind.Application;

/**
 * Created by FANY on 2014/10/28.
 */
public class BitmapHelper
{
    public static Bitmap toRoundCorner(Bitmap bitmap, int pixels)
    {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);

        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        final RectF rectF = new RectF(rect);

        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawRoundRect(rectF, (float) pixels, (float) pixels, paint);

        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        return output;
    }

    public static Bitmap halo(Bitmap bitmap, int delta)
    {
        return halo(bitmap, new Point(bitmap.getWidth() / 2, bitmap.getHeight() / 2), bitmap.getWidth() / 2, delta);
    }

    //    光晕, delta值越小图片会越亮，越大则越暗
    public static Bitmap halo(Bitmap bitmap, Point center, float radius, int delta)
    {
        // 高斯矩阵
        int[] gauss = new int[]{1, 2, 1, 2, 4, 2, 1, 2, 1};

        int width = bitmap.getWidth();
        int height = bitmap.getHeight();
        Bitmap returnBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);


        int[] pixels = new int[width * height];
        bitmap.getPixels(pixels, 0, width, 0, 0, width, height);
        for (int row = 1; row < height - 1; row++)
        {
            for (int col = 1; col < width - 1; col++)
            {
                int idx = 0;
                int distance = (int) (Math.pow(col - center.x, 2) + Math.pow(row - center.y, 2));
                // 不是中心区域的点做模糊处理
                if (distance > radius * radius)
                {
                    int newR = 0;
                    int newG = 0;
                    int newB = 0;
                    for (int rowOffset = -1; rowOffset <= 1; rowOffset++)
                    {
                        for (int colOffset = -1; colOffset <= 1; colOffset++)
                        {
                            int pixColor = pixels[(row + rowOffset) * width + col + colOffset];
                            int pixR = Color.red(pixColor);
                            int pixG = Color.green(pixColor);
                            int pixB = Color.blue(pixColor);

                            newR = newR + pixR * gauss[idx];
                            newG = newG + pixG * gauss[idx];
                            newB = newB + pixB * gauss[idx];
                            idx++;
                        }
                    }
//                    RGB同时乘以一个倍数，修改图片的亮度
                    newR /= delta;
                    newG /= delta;
                    newB /= delta;
                    newR = Math.min(255, Math.max(0, newR));
                    newG = Math.min(255, Math.max(0, newG));
                    newB = Math.min(255, Math.max(0, newB));
                    pixels[row * width + col] = Color.argb(255, newR, newG, newB);
                }
            }
        }

        returnBitmap.setPixels(pixels, 0, width, 0, 0, width, height);
        return returnBitmap;
    }

    public static void loadThumbnailAsync(String filePath, int pixels, ImageView view)
    {
        BitmapThumbnailTask task = new BitmapThumbnailTask(view);
        task.execute(filePath, pixels);
    }

    private static HashMap<Integer, Bitmap> _cachedBitmapResource;

    public static Bitmap loadBitmapResource(int resourceId)
    {
        if (_cachedBitmapResource == null)
        {
            _cachedBitmapResource = new HashMap<Integer, Bitmap>();
        }
        if (_cachedBitmapResource.containsKey(resourceId))
        {
            return _cachedBitmapResource.get(resourceId);
        }
        else
        {
            Bitmap bitmap = BitmapFactory.decodeResource(ContextUtils.getInstance().getResources(), resourceId);
            _cachedBitmapResource.put(resourceId, bitmap);
            return bitmap;
        }
    }

    private static HashMap<String, Bitmap> _cachedThumbnails = new HashMap<String, Bitmap>();
    private static final String CachePath = "Cache";

    private static Bitmap getCachedThumbnail(String filePath)
    {
        String thumbnailKey = CommonUtils.stringToMD5(filePath);
        if (_cachedThumbnails.containsKey(thumbnailKey))
        {
            return _cachedThumbnails.get(thumbnailKey);
        }
        File thumbnailCache = FileHelper.getSubStoragePath(CachePath);
        File[] thumbnails = thumbnailCache.listFiles();
        for (File thumbnail : thumbnails)
        {
            if (thumbnail.getName().equals(thumbnailKey))
            {
                return BitmapFactory.decodeFile(thumbnail.getAbsolutePath());
            }
        }
        return null;
    }

    private static void putCachedThumbnail(String filePath, Bitmap bitmap)
    {
        String thumbnailKey = CommonUtils.stringToMD5(filePath);
        if (_cachedThumbnails.containsKey(thumbnailKey))
        {
            return;
        }
        File thumbnailCache = FileHelper.getSubStoragePath(CachePath);
        String path = FileHelper.combineFileName(thumbnailCache.getAbsolutePath(), thumbnailKey);
        saveBitmap(path, bitmap);
        _cachedThumbnails.put(thumbnailKey, bitmap);
    }

    public static void saveBitmap(String path, Bitmap bitmap)
    {
        File file = new File(path);
        if (file.exists())
        {
            file.delete();
        }
        try
        {
            FileOutputStream outputStream = new FileOutputStream(file);
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, outputStream);
            outputStream.flush();
            outputStream.close();
        }
        catch (FileNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }

    public static Bitmap extractThumbnail(String filePath, int pixels)
    {
        String extension = FileHelper.extractFileExtension(filePath);
        FileKind kind = FileHelper.getFileKindByExtension(extension);
        Bitmap bitmap = null;
        switch (kind)
        {
            case Application:
                bitmap = getCachedThumbnail(filePath);
                if (bitmap == null)
                {
                    PackageManager pm = ContextUtils.getInstance().getPackageManager();
                    PackageInfo pkgInfo = pm.getPackageArchiveInfo(filePath, PackageManager.GET_ACTIVITIES);
                    ApplicationInfo appInfo = pkgInfo.applicationInfo;
                    appInfo.sourceDir = filePath;
                    appInfo.publicSourceDir = filePath;
                    Drawable ico = appInfo.loadIcon(pm);
                    bitmap = ((BitmapDrawable) ico).getBitmap();
                    putCachedThumbnail(filePath, bitmap);
                }
                break;
            case Picture:
                bitmap = getCachedThumbnail(filePath);
                if (bitmap == null)
                {
                    Bitmap sourceBitmap = BitmapFactory.decodeFile(filePath);
                    if (sourceBitmap == null)
                    {
                        return loadBitmapResource(R.drawable.loading);
                    }
                    bitmap = ThumbnailUtils.extractThumbnail(sourceBitmap, Math.min(pixels, sourceBitmap.getWidth()),
                            Math.min(pixels, sourceBitmap.getHeight()));
                    if (sourceBitmap.getWidth() > 128)
                    {
                        putCachedThumbnail(filePath, bitmap);
                    }
                }
                break;
            case Video:
                bitmap = ThumbnailUtils.createVideoThumbnail(filePath, MediaStore.Video.Thumbnails.MICRO_KIND);
                break;
            case Compressed:
            case Configure:
            case Document:
            case Music:
                int resourceId = FileHelper.getResourceIdByFileExtension(extension);
                if (resourceId > 0)
                {
                    bitmap = loadBitmapResource(resourceId);
                }
                else
                {
                    bitmap = loadBitmapResource(R.drawable.file);
                }
                break;
            default:
                bitmap = loadBitmapResource(R.drawable.file);
                break;
        }
        if (bitmap != null)
        {
            bitmap = toRoundCorner(bitmap, Math.min(pixels, bitmap.getWidth()));
        }
        return bitmap;
    }
}

